import * as THREE from 'three';

/**
 * AR系统核心类
 * 负责管理摄像头、3D场景和AR渲染
 */
export class ARSystem {
  private canvas: HTMLCanvasElement;
  private scene: THREE.Scene;
  private camera: THREE.PerspectiveCamera;
  private renderer: THREE.WebGLRenderer;
  private video: HTMLVideoElement;
  private videoTexture: THREE.VideoTexture;
  private raycaster: THREE.Raycaster;
  private mouse: THREE.Vector2;
  private animationId: number | null = null;
  private isInitialized = false;

  constructor(canvas: HTMLCanvasElement) {
    this.canvas = canvas;
    this.scene = new THREE.Scene();
    this.camera = new THREE.PerspectiveCamera(
      75,
      window.innerWidth / window.innerHeight,
      0.1,
      1000
    );
    this.raycaster = new THREE.Raycaster();
    this.mouse = new THREE.Vector2();
    
    // 初始化渲染器
    this.renderer = new THREE.WebGLRenderer({
      canvas: this.canvas,
      alpha: true,
      antialias: true
    });
    this.renderer.setSize(window.innerWidth, window.innerHeight);
    this.renderer.setPixelRatio(window.devicePixelRatio);
    
    // 创建视频元素
    this.video = document.createElement('video');
    this.video.autoplay = true;
    this.video.playsInline = true;
    this.video.muted = true;
    
    // 创建视频纹理
    this.videoTexture = new THREE.VideoTexture(this.video);
    this.videoTexture.minFilter = THREE.LinearFilter;
    this.videoTexture.magFilter = THREE.LinearFilter;
  }

  /**
   * 初始化AR系统
   */
  async init(): Promise<void> {
    try {
      // 获取摄像头权限
      await this.initCamera();
      
      // 设置场景
      this.setupScene();
      
      // 开始渲染循环
      this.startRenderLoop();
      
      this.isInitialized = true;
    } catch (error) {
      console.error('AR系统初始化失败:', error);
      throw error;
    }
  }

  /**
   * 初始化摄像头
   */
  private async initCamera(): Promise<void> {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({
        video: {
          facingMode: 'environment', // 使用后置摄像头
          width: { ideal: 1280 },
          height: { ideal: 720 }
        }
      });

      this.video.srcObject = stream;
      
      return new Promise((resolve, reject) => {
        this.video.onloadedmetadata = () => {
          this.video.play()
            .then(() => resolve())
            .catch(reject);
        };
        this.video.onerror = reject;
      });
    } catch (error) {
      console.error('摄像头初始化失败:', error);
      throw new Error('无法访问摄像头，请检查权限设置');
    }
  }

  /**
   * 设置3D场景
   */
  private setupScene(): void {
    // 创建背景平面
    const geometry = new THREE.PlaneGeometry(2, 2);
    const material = new THREE.MeshBasicMaterial({
      map: this.videoTexture,
      side: THREE.DoubleSide
    });
    const background = new THREE.Mesh(geometry, material);
    background.position.z = -1;
    this.scene.add(background);

    // 添加环境光
    const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
    this.scene.add(ambientLight);

    // 添加方向光
    const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
    directionalLight.position.set(1, 1, 1);
    this.scene.add(directionalLight);
  }

  /**
   * 开始渲染循环
   */
  private startRenderLoop(): void {
    const animate = () => {
      this.animationId = requestAnimationFrame(animate);
      this.render();
    };
    animate();
  }

  /**
   * 渲染场景
   */
  private render(): void {
    if (this.videoTexture) {
      this.videoTexture.needsUpdate = true;
    }
    this.renderer.render(this.scene, this.camera);
  }

  /**
   * 启动摄像头
   */
  async startCamera(): Promise<void> {
    if (!this.isInitialized) {
      await this.init();
    }
    
    if (this.video.paused) {
      await this.video.play();
    }
  }

  /**
   * 停止摄像头
   */
  async stopCamera(): Promise<void> {
    if (this.video.srcObject) {
      const stream = this.video.srcObject as MediaStream;
      stream.getTracks().forEach(track => track.stop());
      this.video.srcObject = null;
    }
  }

  /**
   * 添加3D对象到场景
   */
  addObject(object: THREE.Object3D): void {
    this.scene.add(object);
  }

  /**
   * 从场景移除3D对象
   */
  removeObject(object: THREE.Object3D): void {
    this.scene.remove(object);
  }

  /**
   * 获取指定屏幕坐标的3D对象
   */
  getObjectAt(x: number, y: number): THREE.Object3D | null {
    // 将屏幕坐标转换为标准化设备坐标
    this.mouse.x = (x / window.innerWidth) * 2 - 1;
    this.mouse.y = -(y / window.innerHeight) * 2 + 1;

    // 更新射线投射器
    this.raycaster.setFromCamera(this.mouse, this.camera);

    // 计算射线与对象的交点
    const intersects = this.raycaster.intersectObjects(this.scene.children, true);
    
    if (intersects.length > 0) {
      return intersects[0].object;
    }
    
    return null;
  }

  /**
   * 更新相机位置（基于设备方向）
   */
  updateCameraPosition(): void {
    // 这里可以添加设备方向检测逻辑
    // 使用DeviceOrientationEvent API
  }

  /**
   * 处理窗口大小变化
   */
  handleResize(): void {
    const width = window.innerWidth;
    const height = window.innerHeight;

    this.camera.aspect = width / height;
    this.camera.updateProjectionMatrix();

    this.renderer.setSize(width, height);
  }

  /**
   * 销毁AR系统
   */
  destroy(): void {
    if (this.animationId) {
      cancelAnimationFrame(this.animationId);
    }

    if (this.video.srcObject) {
      const stream = this.video.srcObject as MediaStream;
      stream.getTracks().forEach(track => track.stop());
    }

    this.renderer.dispose();
    this.videoTexture.dispose();
    
    // 清理场景
    this.scene.clear();
  }
}

/**
 * AR吉祥物类
 * 专门用于创建和管理AR吉祥物
 */
export class ARMascot {
  private model: THREE.Object3D;
  private animations: THREE.AnimationClip[] = [];
  private mixer: THREE.AnimationMixer | null = null;

  constructor(modelPath?: string) {
    this.model = new THREE.Group();
    this.createDefaultModel();
  }

  /**
   * 创建默认吉祥物模型
   */
  private createDefaultModel(): void {
    // 创建身体
    const bodyGeometry = new THREE.SphereGeometry(0.5, 32, 32);
    const bodyMaterial = new THREE.MeshPhongMaterial({ 
      color: 0xff6b35,
      shininess: 100
    });
    const body = new THREE.Mesh(bodyGeometry, bodyMaterial);
    body.position.y = 0;
    this.model.add(body);

    // 创建头部
    const headGeometry = new THREE.SphereGeometry(0.3, 32, 32);
    const headMaterial = new THREE.MeshPhongMaterial({ 
      color: 0xff6b35,
      shininess: 100
    });
    const head = new THREE.Mesh(headGeometry, headMaterial);
    head.position.y = 0.8;
    this.model.add(head);

    // 创建眼睛
    const eyeGeometry = new THREE.SphereGeometry(0.05, 16, 16);
    const eyeMaterial = new THREE.MeshBasicMaterial({ color: 0x000000 });
    
    const leftEye = new THREE.Mesh(eyeGeometry, eyeMaterial);
    leftEye.position.set(-0.1, 0.9, 0.25);
    this.model.add(leftEye);
    
    const rightEye = new THREE.Mesh(eyeGeometry, eyeMaterial);
    rightEye.position.set(0.1, 0.9, 0.25);
    this.model.add(rightEye);

    // 创建嘴巴
    const mouthGeometry = new THREE.RingGeometry(0.05, 0.1, 16);
    const mouthMaterial = new THREE.MeshBasicMaterial({ 
      color: 0x000000,
      side: THREE.DoubleSide
    });
    const mouth = new THREE.Mesh(mouthGeometry, mouthMaterial);
    mouth.position.set(0, 0.7, 0.25);
    mouth.rotation.x = Math.PI;
    this.model.add(mouth);

    // 设置模型位置
    this.model.position.set(0, 0, -2);
    this.model.scale.set(1, 1, 1);
  }

  /**
   * 添加动画
   */
  addAnimation(animation: THREE.AnimationClip): void {
    this.animations.push(animation);
  }

  /**
   * 播放动画
   */
  playAnimation(index: number = 0): void {
    if (this.animations[index] && this.mixer) {
      const action = this.mixer.clipAction(this.animations[index]);
      action.play();
    }
  }

  /**
   * 获取3D模型
   */
  getModel(): THREE.Object3D {
    return this.model;
  }

  /**
   * 设置位置
   */
  setPosition(x: number, y: number, z: number): void {
    this.model.position.set(x, y, z);
  }

  /**
   * 设置缩放
   */
  setScale(x: number, y: number, z: number): void {
    this.model.scale.set(x, y, z);
  }

  /**
   * 旋转模型
   */
  rotate(x: number, y: number, z: number): void {
    this.model.rotation.set(x, y, z);
  }

  /**
   * 添加呼吸动画
   */
  addBreathingAnimation(): void {
    const scaleAnimation = new THREE.AnimationClip('breathing', 2, [
      new THREE.VectorKeyframeTrack(
        '.scale[x]',
        [0, 1, 2],
        [1, 1.1, 1]
      ),
      new THREE.VectorKeyframeTrack(
        '.scale[y]',
        [0, 1, 2],
        [1, 1.1, 1]
      ),
      new THREE.VectorKeyframeTrack(
        '.scale[z]',
        [0, 1, 2],
        [1, 1.1, 1]
      )
    ]);
    
    this.addAnimation(scaleAnimation);
  }

  /**
   * 添加跳跃动画
   */
  addJumpAnimation(): void {
    const jumpAnimation = new THREE.AnimationClip('jump', 1, [
      new THREE.VectorKeyframeTrack(
        '.position[y]',
        [0, 0.5, 1],
        [0, 0.5, 0]
      )
    ]);
    
    this.addAnimation(jumpAnimation);
  }
}

/**
 * AR线索管理器
 * 管理AR打卡点的线索信息
 */
export class ARClueManager {
  private clues: Map<string, any> = new Map();

  /**
   * 添加线索
   */
  addClue(pointId: string, clue: any): void {
    this.clues.set(pointId, clue);
  }

  /**
   * 获取线索
   */
  getClue(pointId: string): any {
    return this.clues.get(pointId);
  }

  /**
   * 移除线索
   */
  removeClue(pointId: string): void {
    this.clues.delete(pointId);
  }

  /**
   * 检查线索是否存在
   */
  hasClue(pointId: string): boolean {
    return this.clues.has(pointId);
  }
}

